﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Win32;
using SkypeCore;
using System.IO;
using System.Threading.Tasks;
using System.Threading;
using System.ComponentModel;
using SkypeHistory;

namespace SkypeCleaner
{
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
		private ContactsManager _contactsManager;
		private MessagesManager _messagesManager;
		private string _accountName;

		BackgroundWorker _backgroundWorker = new BackgroundWorker();

		public MainWindow()
		{
			InitializeComponent();
			ShowOpenFileDialog();
		}

		private void ShowOpenFileDialog()
		{
			var openDatabaseDialog = new OpenDatabaseWindow();
			var dialogResult = openDatabaseDialog.ShowDialog();
			var result = dialogResult != null && dialogResult.Value;
			if (result)
			{
				var filePath = openDatabaseDialog.FilePath;
				var databaseValid = false;
				try
				{
					DatabaseConnection.TryToOpen(filePath);
					Init(filePath);
					databaseValid = true;
				}
				catch (Exception exception)
				{
					MessageBox.Show(string.Format("Database open error:{0}", exception.Message), "Error", MessageBoxButton.OK,
									MessageBoxImage.Error);
					ShowOpenFileDialog();
				}
				if (databaseValid)
				{
					try
					{
						contacts.ItemsSource = _contactsManager.Get().OrderBy(n => n.SkypeName).ToList();
						_accountName = _contactsManager.GetSelfName().First();
						Title = _accountName;
					}
					catch (Exception exception)
					{
						MessageBox.Show(string.Format("Incorrect database:{0}", exception.Message), "Error", MessageBoxButton.OK,
									MessageBoxImage.Error);
						ShowOpenFileDialog();
					}
				}

				File.Copy(filePath, filePath + "_backup", true);
			}
			else
			{
				Application.Current.Shutdown();
			}
		}

		private void Init(string databasePath)
		{
			_contactsManager = new ContactsManager(databasePath);
			_messagesManager = new MessagesManager(databasePath);
		}

		private void contacts_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			if (_messagesManager != null && contacts.SelectedIndex != -1)
			{
				GetMessages(false);
			}
		}

		private void butSelectAll_Click(object sender, RoutedEventArgs e)
		{
			GetMessages(true);
		}

		private void butUnselectAll_Click(object sender, RoutedEventArgs e)
		{
			GetMessages(false);
		}

		private void butRemove_Click(object sender, RoutedEventArgs e)
		{
			Cursor = Cursors.Wait;
			_backgroundWorker.WorkerReportsProgress = true;
			_backgroundWorker.DoWork += delegate
											{
												var itemsCount = messages.ItemsSource.OfType<MessageEntry>().Count(n => n.Remove);
												var i = 0;
												foreach (var messageEntry in messages.ItemsSource.OfType<MessageEntry>().Where(n => n.Remove))
												{
													i++;
													_messagesManager.Delete(messageEntry.Message.Id);
													_backgroundWorker.ReportProgress((int)((double)i / itemsCount * 100));
												}
											};
			_backgroundWorker.ProgressChanged += delegate(object obj, ProgressChangedEventArgs args)
													{
														progress.Content =
															args.ProgressPercentage + "%";
													};
			_backgroundWorker.RunWorkerCompleted += delegate
														{
															Cursor = Cursors.Arrow;
															GetMessages(false);
															progress.Content = "Done.";
														};
			_backgroundWorker.RunWorkerAsync();
		}

		private void GetMessages(bool select)
		{
			messages.ItemsSource = _messagesManager.Get(((SkypeContact)contacts.SelectedItem).SkypeName, _accountName).OrderBy(n => n.Date).Select(n => new MessageEntry
			{
				Message = n,
				Remove = select
			}).ToList();
		}
	}
}
